#!/usr/bin/env python
# coding: utf-8
"""
ftp命令：(文件名 目录名不支持中间有空格)
cd remote-dir
dir
get remote-file local-file
put local-file remote-file
delete remote-file
"""
from ftplib import FTP
import logging
import os
import re

FTP_PORT = 21
_FTP_DEBUG_LEVEL = 0

class tnxxx_ftp(object):
    cmd_dic = {}
    
    def __init__(self):
        self.__ftp = FTP()
        self.__ftp.set_debuglevel(_FTP_DEBUG_LEVEL)
        self.__ip = ''
        self.__usr = 'weihu'
        self.__pwd = 'cjhyy300'
        logging.basicConfig(level=logging.INFO,
                        format='%(asctime)s %(levelname)-8s %(name)-16s : %(message)s',
                        # filemode='w')
                        )   
        self.logger = logging.getLogger(self.__class__.__name__)
    
    def connect(self, ip, slot, port,usr=None, pwd=None):
        rtn = False
        self.__ip = ip
        if usr != None and type(usr)==str:
            self.__usr = usr
        if pwd!=None and type(pwd)==str:
            self.__pwd = pwd
        try : 
            print (self.__ftp.connect(self.__ip))
            print (self.__ftp.login(self.__usr, self.__pwd))
            rtn = True
        except:
            rtn = False
        self.logger.info('connect ip %s, port 21 : '%(ip) + ('successed' if rtn else 'failed'))
        return rtn
        
    def disconnect(self):
        try :
            self.__ftp.quit()
        except:
            pass
        self.logger.info('disconnect ip %s, port 21'%(self.__ip))
        return True
 
    def send(self, cmd, timeout = 50):
        if type(cmd) != str:
            self.logger.error("send : cmd type isn't str")
            return 'cmd excute failed'
        self.logger.info(cmd)
        return self._cmd_parse_and_excute(cmd)
                
    def send_only(self, cmd, timeout = 50):
        if type(cmd) != str:
            self.logger.error("send_only : cmd type isn't str")
            return False
        return self._cmd_parse_and_excute(cmd)
        
    def check_default_rtn(self, cmd, rtn_str):
        if rtn_str.find('cmd excute failed') >= 0:
            return False
        return rtn_str[0] == '2'
    
    def _cmd_parse_and_excute(self, cmd):
        if re.match(r"^\s*$", cmd)!=None:
            return '2'
        rtn = 'cmd excute failed'
        cmd_word_list = cmd.split()
        # if not self.cmd_dic.has_key(cmd_word_list[0]):
        if cmd_word_list[0] not in self.cmd_dic:
            self.logger.error("CMD : %s isn't support"%(cmd))
            return rtn
        try :
            rtn = self.cmd_dic[cmd_word_list[0]](self, cmd_word_list)
        except :
            pass
        return rtn
    
    def __cmd_cd(self, cmd_word_list):
        if len(cmd_word_list)!= 2:
            return 'cmd excute failed'
        return self.__ftp.cwd(cmd_word_list[1])    
    cmd_dic['cd'] = __cmd_cd    #cd remote-dir
    
    """
    dir命令返回的格式
    ['  size          date       time       name',
     '--------       ------     ------    --------',
     '    2048    Apr-14-2009  18:28:46   sys               <DIR>',
     '    2048    Apr-16-2009  17:49:04   db                <DIR>',
     '']
    """
    def __cmd_dir(self, cmd_word_list):
        if len(cmd_word_list)!= 1:
            return 'cmd excute failed'
        return str(self.__ftp.nlst())    
    cmd_dic['dir'] = __cmd_dir  #dir

    def __cmd_get(self, cmd_word_list):
        if len(cmd_word_list)!= 3:
            return 'cmd excute failed'
        remote_file = cmd_word_list[1]
        local_file = cmd_word_list[2]
        m = re.match(r'^([a-z]:[\\/](?:[^\\/*?"<>|]+[\\/])*)[^\\/*?"<>|]+$', local_file, re.I)
        if m == None:
            return 'cmd excute failed'
        local_file_dir = m.group(1)
        if not os.path.isdir(local_file_dir):
            os.makedirs(local_file_dir)
        file = open(local_file, 'wb')
        rtn = self.__ftp.retrbinary('RETR %s'%remote_file, file.write)
        file.close()
        return rtn
    cmd_dic['get'] = __cmd_get  #get remote-file local-file
    
    def __cmd_put(self, cmd_word_list):
        if len(cmd_word_list)!= 3:
            return 'cmd excute failed'
        local_file = cmd_word_list[1]
        remote_file = cmd_word_list[2]
        buffersize=1024
        file =open(local_file,'rb')
        rtn = self.__ftp.storbinary('STOR %s'%remote_file,file,buffersize)
        file.close()
        return rtn
    cmd_dic['put'] = __cmd_put  #put local-file remote-file     
    
    def __cmd_delete(self, cmd_word_list):
        if len(cmd_word_list)!= 2:
            return 'cmd excute failed'
        remote_file = cmd_word_list[1]
        return self.__ftp.delete(remote_file)
    cmd_dic['delete'] = __cmd_delete    #delete remote-file
        
    def test(self):
        print ('-'*50)
        print ('-'*50)
        rtn = self.__ftp.nlst('/tffs')
        print ('-'*50)
        print ('-'*50)
        print (rtn)
        print ('-'*50)
        return
        
if __name__ == "__main__":
    host = '192.168.210.144'
    case = tnxxx_ftp()
    print (case.connect(host, 21, 'weihu', 'cjhyy300'))
#    case.test()
    print ('#'*50)
    rtn = case.send('cd /tffs')
    print (rtn)
    print ('#'*50)
    rtn = case.send('dir')
    print (rtn)
    print ('#'*50)
    rtn = case.send('put d:/zebos.cfg zebos.cfg')
    print (rtn)
    print ('#'*50)
    rtn = case.send('get zebos.cfg d:/ddd/3333/6665_a/df2a\z.tmp')
    print (rtn)
    print ('#'*50)
    rtn = case.send('delete zebos.cfg')
    print (rtn)
    print ('#'*50)
    print (case.disconnect())
